package org.nvframe.factory;

import java.lang.reflect.Constructor;

import org.nvframe.component.AbstractComponent;
import org.nvframe.entity.Entity;
import org.nvframe.exception.NVFrameException;
import org.nvframe.util.settings.SettingsObj;

/**
 * 
 * @author Nik Van Looy
 */
public class ComponentFactory {
	private static final ComponentFactory _instance = new ComponentFactory();
	
	public static ComponentFactory getInstance() {
		return _instance;
	}
	
	private ComponentFactory() {
	}
	
	/**
	 * Instantiates a component from a given classname 
	 * uses the Java reflection API
	 * 
	 * @param componentId
	 * @param settings
	 * @param owner
	 * @return Component the instantiated component
	 * @throws NVFrameException 
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public AbstractComponent getComponent(String componentId, SettingsObj settings, Entity owner) 
			throws NVFrameException {
		
		String componentCls = settings.getString("cls");
		
		AbstractComponent comp = null;
		
		try {
			Class cls = Class.forName(componentCls);
			Constructor c = cls.getConstructor(String.class, Entity.class, SettingsObj.class);
			comp = (AbstractComponent) c.newInstance(componentId, owner, settings);
		} catch (Exception e) {
			throw new NVFrameException("Component [cls="+componentCls+", entity="+owner.getId()+"] could not be instantiated", e);
		}

		return comp;
	}
}
